﻿//AcademicPlanner - course registration planning web app.
//Copyright (C) 2009  Boubacar Diallo

//This program is free software; you can redistribute it and/or
//modify it under the terms of the GNU General Public License
//as published by the Free Software Foundation; either version 2
//of the License, or (at your option) any later version.

//This program is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//GNU General Public License for more details.

//You should have received a copy of the GNU General Public License
//along with this program; if not, write to the Free Software
//Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Globalization;
using System.Web;

namespace AcademicPlanner.Framework.Helpers
{
	/// <summary>
	/// SessionHelper provides static helper methods for manipulation
	/// of session data.
	/// </summary>
	/// <since>1.0</since>
	public static class SessionHelper
	{
		private static HttpSessionStateBase SESSION;


		/// <summary>
		/// Resumes a web session. This method sets the
		/// internal session pointer to the provided session
		/// object.
		/// </summary>
		/// <param name="pSession">The web session to resume to.</param>
		/// <since>1.0</since>
		public static void Resume(HttpSessionStateBase pSession)
		{
			if (SESSION == null) SESSION = pSession;

			SetUserCulture("");
			Set("StatusMessages.Success", new List<string>());
			Set("StatusMessages.Info", new List<string>());
			Set("Presentation.Skin", "");
			Set("Presentation.Theme", "");
		}

		/// <summary>
		/// Stores data to the session under the provided
		/// key. This method does so only if the provided
		/// key does not exist yet.
		/// </summary>
		/// <param name="pKey">The key to store the data under.</param>
		/// <param name="pObj">The data to store.</param>
		/// <since>1.0</since>
		public static void Set(string pKey, object pObj)
		{
			if (Get(pKey) == null)
				SESSION.Add(pKey, pObj);
		}

		/// <summary>
		/// Stores data to the session under the provided
		/// key. This method does so regardless of the provided
		/// key existing or not.
		/// </summary>
		/// <param name="pKey">The key to store the data under.</param>
		/// <param name="pObj">The data to store.</param>
		/// <since>1.0</since>
		public static void Reset(string pKey, object pObj)
		{
			if (Get(pKey) != null)
				SESSION.Remove(pKey);

			SESSION[pKey] = pObj;
		}

		/// <summary>
		/// Retrieves data stored in the session under the
		/// provided key.
		/// </summary>
		/// <param name="pKey">The key the data is stored under.</param>
		/// <returns>The data stored under the key or <c>null</c>.</returns>
		/// <since>1.0</since>
		public static object Get(string pKey)
		{
			return SESSION[pKey];
		}

		/// <summary>
		/// Gets the identifier (username) of the current user; it is
		/// stored under "User.Name".
		/// </summary>
		/// <returns>The identifier (username) of the current user or <c>""</c>.</returns>
		/// <since>1.0</since>
		public static string GetUserName()
		{
			return ((string)Get("User.Name")) ?? "";
		}

		/// <summary>
		/// Gets the password of the current user; it is
		/// stored under "User.Password".
		/// </summary>
		/// <returns>The password of the current user or <c>""</c>.</returns>
		/// <since>1.0</since>
		public static string GetUserPassword()
		{
			return ((string)Get("User.Password")) ?? "";
		}

		/// <summary>
		/// Gets the culture of the current user; it is
		/// stored under "User.Culture".
		/// </summary>
		/// <returns>The culture of the current user or <c>""</c>.</returns>
		/// <since>1.0</since>
		public static string GetUserCulture()
		{
			return ((string)Get("User.Culture")) ?? "";
		}

		/// <summary>
		/// Gets whether the current user is authenticated or not.
		/// </summary>
		/// <returns>Whether the current user is authenticated or not.</returns>
		/// <since>1.0</since>
		public static bool IsUserAuthenticated()
		{
			return ((bool?)Get("User.IsAuthenticated") ?? false);
		}

		/// <summary>
		/// Sets the culture of the current user; it is
		/// stored under "User.Culture".
		/// </summary>
		/// <param name="pCulture">The culture of the current user.</param>
		/// <seealso cref="M:Set"/>
		/// <since>1.0</since>
		public static void SetUserCulture(string pCulture)
		{
			Set("User.Culture", pCulture);
		}

		/// <summary>
		/// Resets the culture of the current user; it is
		/// stored under "User.Culture".
		/// </summary>
		/// <param name="pCulture">The culture of the current user.</param>
		/// <seealso cref="M:Reset"/>
		/// <since>1.0</since>
		public static void ResetUserCulture(string pCulture)
		{
			Reset("User.Culture", pCulture);
		}

		/// <summary>
		/// Resets the password of the current user; it is
		/// stored under "User.Password".
		/// </summary>
		/// <param name="pPassword">The new password.</param>
		/// <seealso cref="M:Reset"/>
		/// <since>1.0</since>
		public static void ResetUserPassword(string pPassword)
		{
			Reset("User.Password", pPassword);
		}

		/// <summary>
		/// Resets the username of the current user; it is
		/// stored under "User.Name".
		/// </summary>
		/// <param name="pName">The new username.</param>
		/// <seealso cref="M:Reset"/>
		/// <since>1.0</since>
		public static void ResetUserName(string pName)
		{
			Reset("User.Name", pName);
		}

		/// <summary>
		/// Resets whether the current user is authenticated or not;
		/// it is stored under "User.IsAuthenticated".
		/// </summary>
		/// <param name="pVal">The new value.</param>
		/// <seealso cref="M:Reset"/>
		/// <since>1.0</since>
		public static void ResetIsUserAuthenticated(bool pVal)
		{
			Reset("User.IsAuthenticated", pVal);
		}

		/// <summary>
		/// Adds a new message to the stack of status messages 
		/// indicating success of actions performed by the user.
		/// They are stored under "StatusMessages.Success".
		/// </summary>
		/// <param name="pMsg">The new message to add.</param>
		/// <seealso cref="M:GetSuccessStatusMessages"/>
		/// <seealso cref="M:Reset"/>
		/// <since>1.0</since>
		public static void AddSuccessStatusMessage(string pMsg)
		{
			var vList = GetSuccessStatusMessages();
			vList.Add(pMsg);
			Reset("StatusMessages.Success", vList);
		}

		/// <summary>
		/// Gets the stack of messages indicating success of 
		/// actions performed by the user. They are stored under 
		/// "StatusMessages.Success".
		/// </summary>
		/// <returns>The stack of messages.</returns>
		/// <since>1.0</since>
		public static List<string> GetSuccessStatusMessages()
		{
			return (List<string>)Get("StatusMessages.Success");
		}

		/// <summary>
		/// Adds a new message to the stack of status messages 
		/// calling the user's attention on the actions he performed.
		/// They are stored under "StatusMessages.Info".
		/// </summary>
		/// <param name="pMsg">The new message to add.</param>
		/// <seealso cref="M:GetInfoStatusMessages"/>
		/// <seealso cref="M:Reset"/>
		/// <since>1.0</since>
		public static void AddInfoStatusMessage(string pMsg)
		{
			var vList = GetInfoStatusMessages();
			vList.Add(pMsg);
			Reset("StatusMessages.Info", vList);
		}

		/// <summary>
		/// Gets the stack of messages calling the user's attention on 
		/// the actions he performed. They are stored under 
		/// "StatusMessages.Info".
		/// </summary>
		/// <returns>The stack of messages.</returns>
		/// <since>1.0</since>
		public static List<string> GetInfoStatusMessages()
		{
			return (List<string>)Get("StatusMessages.Info");
		}

		/// <summary>
		/// Clears the stacks of status messages.
		/// This method basically resets the stack
		/// to empty ones.
		/// </summary>
		/// <since>1.0</since>
		public static void ClearStatusMessages()
		{
			Reset("StatusMessages.Success", new List<string>());
			Reset("StatusMessages.Info", new List<string>());
		}

		/// <summary>
		/// Gets the anti-forgery token that was last sent
		/// to the user agent. It is stored under "Presentation.PostSignatureToken".
		/// </summary>
		/// <returns>The anti-forgery token or <c>null</c>.</returns>
		/// <since>1.0</since>
		public static string GetPostSignatureToken()
		{
			return ((string)Get("Presentation.PostSignatureToken")) ?? "";
		}

		/// <summary>
		/// Resets the anti-forgery token to a new one that is
		/// being sent to the user agent.
		/// </summary>
		/// <param name="pToken">The new anti-forgery token.</param>
		/// <since>1.0</since>
		public static void ResetPostSignatureToken(string pToken)
		{
			Reset("Presentation.PostSignatureToken", pToken);
		}
	}
}
